package com.xunk.equipment.service.dnake.service.impl;

import com.xunk.common.core.constant.CacheConstants;
import com.xunk.common.core.constant.DnakeConstants;
import com.xunk.common.core.domain.EquipmentResponse;
import com.xunk.common.core.enums.dnake.DnakeActionEnum;
import com.xunk.common.core.enums.dnake.DnakeDeviceTypeEnum;
import com.xunk.common.core.utils.IdUtils;
import com.xunk.common.redis.service.RedisService;
import com.xunk.common.security.utils.SecurityUtils;
import com.xunk.equipment.domain.EquipmentDO;
import com.xunk.equipment.mapper.EquipmentMapper;
import com.xunk.equipment.service.BaseService;
import com.xunk.equipment.service.IEquipmentService;
import com.xunk.equipment.service.dnake.DnakePublishComponent;
import com.xunk.equipment.service.dnake.vo.DnakeMqttRequestDataMessage;
import com.xunk.equipment.vo.response.DoorWindowSensorInfoResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service("dnake-door-window-sensor")
@Slf4j
public class DnakeDoorSenServiceImpl implements IEquipmentService {

    @Autowired
    DnakePublishComponent dnakePublishComponent;
    @Autowired
    protected RedisService redisService;
    @Autowired
    @Lazy
    BaseService baseService;
    @Autowired
    EquipmentMapper equipmentMapper;

    @Override
    public EquipmentResponse getEquipmentInfo(EquipmentDO equipmentDO) {
        DoorWindowSensorInfoResponse deviceResponse = new DoorWindowSensorInfoResponse();
        Boolean armingStateByDeviceSn = equipmentMapper.getArmingStateByDeviceSn(equipmentDO.getDeviceSn());
        deviceResponse.setArming(armingStateByDeviceSn);

        deviceResponse.setDeviceSn(equipmentDO.getDeviceSn());

        deviceResponse.setSupplier(equipmentDO.getSupplier());
        deviceResponse.setCandidateModel(baseService.getCandidateModel(equipmentDO.getDeviceBaseId()));
        return deviceResponse;
    }

    /**
     * 布撤防
     *
     * @param equipmentDO 当前设备信息，包含设备id，设备厂商
     * @param type        控制类型，如温度、开关、模式
     * @param value       操作目标值  如 20°(20)、open(true)、冷风模式(3)
     * @return
     */
    @Override
    public Boolean control(EquipmentDO equipmentDO, String type, String value) {
        try {
            String deviceSn = equipmentDO.getDeviceSn();

            // 更新数据库、发送websocket 放到mqttListener中，成功返回后才更改数据库

            String messageId = IdUtils.simpleUUID();
            // 放到redis种，返回后知道是哪个用户(userId)发送的具体消息；
            Map<String, Object> map = new HashMap<>();
            // 获取userId
            Long userId = SecurityUtils.getUserId(false);
            map.put("userId", userId);
            map.put("deviceType", equipmentDO.getDeviceType());
            map.put("type", type);
            map.put("value", value);
            map.put("deviceSn", deviceSn);
            map.put("deptId", equipmentDO.getDeptId());
            redisService.setCacheObject(CacheConstants.DNAKE_CONTROL_INFO + messageId, map, 1, TimeUnit.MINUTES);

            DnakeMqttRequestDataMessage vo = new DnakeMqttRequestDataMessage();
            String[] device = deviceSn.split("-");
            DnakeDeviceTypeEnum typeEnum = DnakeDeviceTypeEnum.getDeviceTypeEnumByType(equipmentDO.getDeviceType());
            Integer devType = Integer.valueOf(typeEnum.getCode().split("-")[0]);
            vo.setCmd(value)
                    .setUuid(messageId)
                    .setAction(DnakeActionEnum.CTRLDEF.getCode())
                    .setDevType(devType)
                    .setDevNo(Integer.valueOf(device[1]))
                    .setDevCh(Integer.valueOf(type));

            // 设备绑定的网关deviceName
            String toDev = deviceSn.substring(0, deviceSn.indexOf("-"));

            dnakePublishComponent.publish(vo, toDev, DnakeConstants.DEFENCE);
            return true;
        } catch (Exception e) {
            log.error("设备发送MQTT消息错误：", e);
            return false;
        }
    }

}
